﻿# -*- coding: utf_8 -*-
from Transformation import Transformation
import weakref

class Bone:
    def __init__(self):
        self._id = '-1'
        self._parentId = '-1'
        self._name = ''

        self._aniTranslation = []
        self._aniRotation = []
        self._aniScale = []
        self._aniScaleRotation = []
        
        self._transformation = Transformation()
        
    def Parse(self, boneNode, boneList, meshBone, meshBoneList):
        try:
            self._parentId = boneNode.getAttribute('ParentID')
        except:
            pass
            
        self._id = boneNode.getAttribute('NodeID')
        self._name = boneNode.getAttribute('Name')
        
        for node in boneNode.childNodes:
            if node.nodeName == 'NodeTM':
                for n in node.childNodes:
                    if n.nodeName == 'Translation':
                        value = n.firstChild.nodeValue
                        pos = map(float, value.split(' '))
                        assert(len(pos) == 3)
                        self._transformation._position = pos
                    elif n.nodeName == 'Rotation':
                        value = n.firstChild.nodeValue
                        rot = map(float, value.split(' '))
                        assert(len(rot) == 4)
                        self._transformation._rotation = rot
                    elif n.nodeName == 'Scale':
                        value = n.firstChild.nodeValue
                        scale = map(float, value.split(' '))
                        assert(len(scale) == 7)
                        self._transformation._scale = [scale[0], scale[1], scale[2]]
                        self._transformation._scaleRotation = [scale[3], scale[4], scale[5], scale[6]]
            #elif node.nodeName == 'TMController':
            #    self.__ParseAnimation(node)
            elif node.nodeName == 'MK3DE_ANIMATION':
                self.__ParseMK3DEAnimation(node)
            elif node.nodeName == 'Node' and (node.getAttribute('NodeType') == 'Bone' or node.getAttribute('NodeType') == 'Helper'):
                bone = Bone()
                boneList.append(bone)
                bone.Parse(node, boneList, meshBone, meshBoneList)   
            elif meshBone and node.nodeName == 'Node' and not (node.getAttribute('Name') in meshBoneList):
                bone = Bone()
                boneList.append(bone)
                bone.Parse(node, boneList, meshBone, meshBoneList)
  
    def __ParseMK3DEAnimation(self, node):
        for n in node.childNodes:
            if n.nodeName == 'Sample':
                for sub in n.childNodes:
                    if sub.nodeName == 'Translation':
                        value = sub.firstChild.nodeValue
                        pos = map(float, value.split(' '))
                        assert(len(pos) == 3)
                        #for idx in xrange(0, len(pos)):
                        #    if abs(pos[idx]) < 1e-5:
                        #        pos[idx] = 0
                        self._aniTranslation.append(pos)
                    elif sub.nodeName == 'Rotation':
                        value = sub.firstChild.nodeValue
                        rot = map(float, value.split(' '))
                        assert(len(rot) == 4)
                        #for idx in xrange(0, len(rot)):
                        #    if abs(rot[idx]) < 1e-5:
                        #        rot[idx] = 0                        
                        self._aniRotation.append(rot)
                    elif sub.nodeName == 'Scale':
                        value = sub.firstChild.nodeValue
                        scale = map(float, value.split(' '))
                        #for idx in xrange(0, len(scale)):
                        #    if abs(scale[idx]) < 1e-5:
                        #        scale[idx] = 0                          
                        assert(len(scale) == 7)
                        sc = [scale[0], scale[1], scale[2]]
                        rsc = [scale[3], scale[4], scale[5], scale[6]]
                        self._aniScale.append(sc)
                        self._aniScaleRotation.append(rsc)
                    
    def __ParseAnimation(self, node):
        for n in node.childNodes:
            if n.nodeName == 'PRSController':
                bipAnimation = False
                for subNode in n.childNodes:
                    if subNode.nodeName == 'NodeTM':
                        bipAnimation = True
                        break
                        
                if bipAnimation:
                    for subNode in n.childNodes:
                        if subNode.nodeName == 'NodeTM':
                            self.__ParseBipAnimation(subNode)
                            break
                else:                
                    for subNode in n.childNodes:
                        if subNode.nodeName == 'Position':
                            self.__ParseAnimationPosition(subNode)
                        elif subNode.nodeName == 'Rotation':
                            self.__ParseAnimationRotation(subNode)

    def __ParseBipAnimation(self, node):         
        for n in node.childNodes:
            if n.nodeName == 'Sample':
                for subNode in n.childNodes:
                    if subNode.nodeName == 'Translation':
                        self.__ParseTranslation(subNode)
                    elif subNode.nodeName == 'Rotation':
                        self.__ParseRotation(subNode)
                    elif subNode.nodeName == 'Scale':
                        self.__ParseScale(subNode)

    def __ParseTranslation(self, node):
        value = node.firstChild.nodeValue
        pos = map(float, value.split(' '))
        assert(len(pos) == 3)
        self._aniTranslation.append(pos)
        
    def __ParseRotation(self, node):
        nodeValue = node.firstChild.nodeValue
        rot = map(float, nodeValue.split(' '))
        assert(len(rot) == 4)
        self._aniRotation.append(rot)
        
    def __ParseScale(self, node):
        nodeValue = node.firstChild.nodeValue
        scale = map(float, nodeValue.split(' '))
        assert(len(scale) == 7)
        s = scale[:3]
        r = scale[3:]
        self._aniScale.append(s)
        self._aniScaleRotation.append(r)
                           
    def __ParseAnimationPosition(self, node):
        for n in node.childNodes:
            if n.nodeName == 'Sample':
                self.__ParseTranslation(n)
                        
    def __ParseAnimationRotation(self, node):
        for n in node.childNodes:
            if n.nodeName == 'Sample':
                self.__ParseRotation(n)